package aden.Generic;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;



public class GenIconMenu extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener
{
    protected GenMain mMain;
    public GenMain GetMain() {return mMain;}

    public int mIconSpacing;
    
    public class RenderingThread extends Thread {
        private SurfaceHolder mSurfaceHolder;
        private Context mContext;
        private Handler mHandler;
        private int mCanvasHeight = 1;
        private int mCanvasWidth = 1;
        private GenIconMenu mView;
        private boolean mRun = false;
        private Bitmap mBitmap;
        private Paint mPaint;
        private boolean mIsRedraw = false;

        public RenderingThread(SurfaceHolder surfaceHolder, 
                              GenIconMenu inView,
                              Context       context,
                              Handler       handler) 
        {
            mView = inView;
            // get handles to some important objects
            mSurfaceHolder = surfaceHolder;
            mHandler = handler;
            mContext = context;

            Resources res = context.getResources();
            
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setARGB(255, 255, 255, 255);

            mBitmap = Bitmap.createBitmap(mCanvasWidth,mCanvasHeight,Bitmap.Config.ARGB_8888);
            Refresh();
        }
        
        @Override
        public void run() {
            while (mRun) {
                if (mIsRedraw)
                {
                Canvas c = null;
                try {
                    
                    c = mSurfaceHolder.lockCanvas(null);
                    if (c != null)
                    {
                        synchronized (mSurfaceHolder) {
                           doDraw(c);
                        }
                    }
                } finally {
                    // do this in a finally so that if an exception is thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        mSurfaceHolder.unlockCanvasAndPost(c);
                    }
                }
                }
            }
        }

        
        public void setRunning(boolean b) {
            mRun = b;
        }

        /* Callback invoked when the surface dimensions change. */
        public void setSurfaceSize(int width, int height) {
            // synchronized to make sure these all change atomically
            synchronized (mSurfaceHolder) {
                mCanvasWidth = width;
                mCanvasHeight = height;
                
                if (mMain == null)
                {
                    return;
                }
                mBitmap = Bitmap.createBitmap(mCanvasWidth,mCanvasHeight,Bitmap.Config.ARGB_8888);
                Refresh();
            }
        }

        public boolean Refresh()
        {
            if (mMain == null)
            {
                return false;
            }
            mBitmap.eraseColor(Color.BLACK);
            Canvas canvas = new Canvas(mBitmap);
            // on parcourt le contenu de mView.mHierAction
            float theY = 0;
            if (mHierAction != null)
            {
            for (GenAction action : mHierAction.GetContent()) {
		canvas.drawBitmap(action.GetIcon(), 0, theY, mPaint);
                 theY = theY + action.GetHeight() + mIconSpacing;
            }
            }
            mIsRedraw = true;
            return true;
        }
        
        private void doDraw(Canvas canvas)
        {
            canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        }
    }
    

    protected RenderingThread mThread;
    public GenActionHier mHierAction;

    private GenAction FindAction(float inX,
                                      float inY)
    {
        // on parcourt le contenu de mView.mHierAction
        float theY = 0;
        for (GenAction action : mHierAction.GetContent()) {
            theY = theY + action.GetHeight();
             if (inY < theY)
             {
                 return action;
             }
             theY = theY + mIconSpacing;
        }

        return null;
    }

    public boolean onTouch(View inView,MotionEvent inEvent)
    {
        if (inEvent.getAction() == inEvent.ACTION_UP)
        {
            // on cherche sur quel bouton l'utilisateur a appuye
            GenAction theAction = FindAction(inEvent.getX(),inEvent.getY());
            if (theAction != null)
            {
                return theAction.Process();
            }
        }
        return true;
    }

    protected Context mContext;
    public GenIconMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mHierAction = null;

        mIconSpacing = 3;
        
        // register our interest in hearing about changes to our surface
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);
        setOnTouchListener(this);

        
        mThread = new RenderingThread(holder, this,context, new Handler() {
            @Override
            public void handleMessage(Message m) {
//                mStatusText.setVisibility(m.getData().getInt("viz"));
//                mStatusText.setText(m.getData().getString("text"));
            }
        });

        // create mThread only; it's started in surfaceCreated()
        setFocusable(true); // make sure we get key events
    }

    public void Init(GenMain inMain)
    {
        mMain = inMain;

        mThread.Refresh();
    }
    
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        mThread.setSurfaceSize(width, height);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // start the mThread here so that we don't busy-wait in run()
        // waiting for the surface to be created
        mThread.setRunning(true);
        mThread.start();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // we have to tell mThread to shut down & wait for it to finish, or else
        // it might touch the Surface after we return and explode
        boolean retry = true;
        mThread.setRunning(false);
        while (retry) {
            try {
                mThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
    }
    public boolean SetHierAction(GenActionHier inHier)
    {
        mHierAction = inHier;
        mThread.Refresh();
        return true;
    }
    
    public GenActionHier GetHierAction() {return mHierAction;}
    
    public boolean Refresh()
    {
        mThread.Refresh();
        return true;
    }
}
